#ifndef __HEAD_H__
#define __HEAD_H__

#include <my_header.h>

// 如果是正常日志，使用这个宏函数，传递打印信息
#define LOG_INFO_MSG(msg) \
    do {\
        syslog(LOG_INFO, "%s\n", msg);\
    } while(0)

// 如果是记录错误日志，使用LOG_ERR_MSG宏函数
#define LOG_ERR_MSG(msg) \
    do {\
        syslog(LOG_ERR, "%s\n", msg);\
    } while(0)

typedef enum 
{
    C_OP_CD,
    C_OP_LS,
    C_OP_GETS,
    C_OP_GETS_BEGIN,
    C_OP_GETS_SUCESS,
    C_OP_PUTS,
    C_OP_PUTS_BEGIN,
    C_OP_RMDIR,
    C_OP_MKDIR,
    C_OP_REMOVE,
    C_OP_PWD,
    
    C_LINK_START,
    C_LINK_CLOSE,

    RES_CD,
    RES_LS,
    RES_GETS,
    RES_PUTS,
    RES_GETS_SUCESS,
    RES_GETS_FINISH,
    RES_PUTS_SUCESS,
    RES_PUTS_FINISH,
    RES_RMDIR,
    RES_MKDIR,
    RES_REMOVE,
    RES_PWD,

    RES_ERR_1, //用户所在虚拟目录打不开，清空客户端栈
    RES_ERR_2 //用户操作目标目录打不开，返回错误信息
} MSG_TYPE;

typedef struct
{
    MSG_TYPE type;
    int vir_path_len;
    char vir_path_val[1024];
    int args_len;
    char args_val[1024];
}RequestPackage;

typedef struct
{
    MSG_TYPE type;
    int vir_path_len;
    char vir_path_val[1024];
    int args_len;
    char args_val[1024];
}ResponsePackage;

typedef struct taskNode_s {
    int netfd;
    int* epfd;
    int client_id;
    MSG_TYPE type;
    char virtualPath[1024]; // 工作目录/虚拟目录
    char args[1024];        // 文件名或者目录名
    struct taskNode_s *pNext;
} taskNode_t;

typedef struct
{
    taskNode_t *pFront;
    taskNode_t *pRear;
    int queuesize;
} taskQueue_t;

typedef struct pthread_data_s {
    pthread_t *ptidarr;
    int workernum;
} pthread_data_t;
 
// 服务端的共享资源
typedef struct 
{
    pthread_data_t  *pthread_data;
    int  *pclient_info;          // 每次新建连接之后需要更新client_info 
    int *exitflag;  // 退出标志位
    pthread_mutex_t *mutex_client_info;  // 用于client_info 

    taskQueue_t taskqueue;

    pthread_mutex_t *mutex_taskqueue;    // 用于任务队列的修改
    pthread_cond_t *cond;                // 用于taskqueue的主仆线程同步 
    int *epfd;
} shareRes_t;

// 服务端链栈
typedef struct node_S
{
    char subpath[128];
    struct node_S* front;
    struct node_S* back; 
}ServerVirtualPathNode;

typedef struct 
{
    ServerVirtualPathNode* head;
    ServerVirtualPathNode* tail;
    int size;
}ServerVirtualPathStack;



typedef struct user_data_s
{
    int user_id;
    char user_name[512];
    char secret_password[512];
} user_data;

//server_api.c
int server_cd(const RequestPackage *prequest, char *serverDir, int netfd);
int server_ls(const RequestPackage *prequest, char *serverDir, int netfd);
int server_pwd(const RequestPackage *prequest, char *serverDir, int netfd);
int server_mkdir(const RequestPackage *prequest, char *serverDir, int netfd);
int server_rmdir(const RequestPackage *prequest, char *serverDir, int netfd);

int server_rmfile(const RequestPackage *prequest, char *serverDir, int netfd);
int server_puts(const RequestPackage *prequest,int netfd,int* epfd);
int server_puts_mmap(const RequestPackage *prequest,int netfd,int* epfd);
int server_puts_mmap2(const RequestPackage *prequest,int netfd,int* epfd);
int s_puts_from_path(ResponsePackage *presponse, char *puts_from_path);
int server_gets(const RequestPackage *prequest,int netfd,int* epfd);
int server_gets_mmap(const RequestPackage *prequest,int netfd,int* epfd);
//int server_gets_mmap2(const RequestPackage *prequest,int netfd,int* epfd);
int s_gets_save_path(ResponsePackage *presponse, char *gets_save_path);

//服务端解析器
//int resolver(RequestPackage *prequest);

// 服务端函数
int epollAdd(int epfd, int addfd, int trigger);
int epollDel(int epfd, int delfd);

// 初始化TCP连接
int initTcp(char *ip, char *port);

// 消息队列相关
int init_queue(taskQueue_t *queue);
int tail_insert(taskQueue_t *q, taskNode_t *new_node);
taskNode_t* head_delete(taskQueue_t *q);
taskNode_t *in_node(int netfd, int client_id, MSG_TYPE type, char *virtualPath, int virtualPath_len, char *args, int args_len);
void print_node(taskNode_t *go);

// 创建与初始化子线程
int init_pthread_data(pthread_data_t *pthread_data, int pthread_num);
int makeworker(shareRes_t *share,int *epfd, pthread_data_t *pthread_data, int *clientInfo, int *exitFlag, pthread_mutex_t *mutex_client_info, taskQueue_t *queue_arr,pthread_mutex_t *long_queue_mutex,pthread_mutex_t *short_queue_mutex,pthread_cond_t *long_queue_cond,pthread_cond_t *short_queue_cond);
// 子线程入口与工作函数
void *pthread_enter(void *arg);
int pthread_func(taskNode_t *get_node,RequestPackage* sharedRequest);

// 链栈操作函数
ServerVirtualPathStack* ServerVirtualPathStack_init();
int ServerVirtualPathStack_print(ServerVirtualPathStack* p,char* str);
int ServerVirtualPathStack_push(ServerVirtualPathStack *stack,char *subpath);
int ServerVirtualPathStack_pop(ServerVirtualPathStack *stack);

// 将字符串形式路径压栈道链栈中
int pathTostack(ServerVirtualPathStack *pstack, char *path);




int recvn(int netfd,void* buf,long len,long* pProcessed);

int ErrCheck_ClientClose(int ret,int netfd,int epfd,pthread_mutex_t* mtx,int* clientInfo);
extern char * serverDir;
// server_cd
// 判断路径是否合法，合法返回RES_CD以及value内存储拼接过后的路径，失败返回RES_ERR2,value内存储错误原因
// client_cd
// 通过type判断是否更新，成功，更新栈，失败，打印错误，不更新

//server_ls
//检查ls路径是否已更改，open打不开，说明已更改，返回RES_ERR2，否则，value内部存储内容，type：RES_LS
//client_ls
//如果type==RES_LS,打印value,RES_ERR，打印错误原因，清空栈

//server_pwd
//client_pwd


//serverputs


#endif
